# -*- coding: utf-8 -*-
# The service
# $Id$

from twisted.application.service import Service
from twisted.internet import reactor
from txpostgres import txpostgres
from twistedschedule.task import ScheduledCall
from twistedschedule.cron import CronSchedule
from parser import UDPSyslog
from pkg_resources import load_entry_point

class BaseService(Service):
    """ Base logic """
    
    def startService(self):
        # Attach sources
        for source in self.sources_spec:
            try:
                source_obj = load_entry_point('grdlog',
                                              'grdlog.source',
                                              source.type)(source.data)
            except ImportError: # no entry-point, log it
                continue

            source_obj.attach(reactor)
            try:
                self.sources[source.id] = source_obj
            except AttributeError: # no id
                pass

        # Listen notifications of source change
        con = txpostgres.Connection()
        con.addNotifyObserver(self.observer)
        con.connect(**self.conf.dsn
                     ).addCallback(lambda _: con.runOperation("listen source"))
        
        # Setup rotation if configured
        rotation = self.conf.rotation
        if rotation.schedule:
            task = ScheduledCall(self.backend.rotate, rotation.number)
            task.start(CronSchedule(rotation.schedule))
    
    def stopService(self):
        for source in self.sources.itervalues():
            source.detach(reactor)
    
    def observer(self, event):
        if event.payload:
            action, id = event.payload.split()
            if action == 'del':
                source = self.sources[id]
                source.detach(reactor)
                del self.sources[id]
            elif action == 'add':
                pass
    
    def __init__(self, conf):
        self.conf = load_entry_point('grdlog', 'grdlog.conf', conf)
        self.backend = load_entry_point('grdlog',
                                        'grdlog.backend',
                                        self.conf.backend
                                        )(self.conf.dsn)
        try:
            self.sources_spec = self.conf.sources
        except AttributeError:
            self.sources_spec = self.backend.sources
        self.sources = {}
